#!/bin/bash

# XappTool 平台部署脚本
# 自动处理前端代码混淆和部署

set -e

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# 默认配置
ENVIRONMENT="production"
DEPLOY_TYPE="saas"  # saas: SaaS模式, private: 私有化部署
OBFUSCATION_LEVEL="heavy"
CREATE_BACKUP=true
VERIFY_DEPLOYMENT=true
SKIP_TESTS=false

# 部署路径
DEPLOY_ROOT="/var/www/xapptool"
BACKUP_ROOT="/var/backups/xapptool"
LOG_FILE="/var/log/xapptool-deploy.log"

# 显示帮助
show_help() {
    echo -e "${CYAN}=== XappTool 平台部署脚本 ===${NC}"
    echo
    echo -e "${YELLOW}用法:${NC} $0 [选项]"
    echo
    echo -e "${YELLOW}环境选项:${NC}"
    echo "  -e, --environment <env>     部署环境 (development, staging, production)"
    echo "  -t, --type <type>         部署类型 (saas, private)"
    echo "  -o, --obfuscation <level> 混淆级别 (light, medium, heavy)"
    echo
    echo -e "${YELLOW}部署选项:${NC}"
    echo "  --deploy-root <path>       部署根目录"
    echo "  --backup-root <path>       备份根目录"
    echo "  --skip-backup             跳过备份"
    echo "  --skip-verify             跳过部署验证"
    echo "  --skip-tests              跳过测试"
    echo
    echo -e "${YELLOW}其他选项:${NC}"
    echo "  -h, --help                显示帮助信息"
    echo "  -v, --verbose             详细输出"
    echo
    echo -e "${YELLOW}示例:${NC}"
    echo "  $0 -e production -t saas -o heavy"
    echo "  $0 --environment staging --type private --obfuscation medium"
    echo "  $0 -e development --skip-backup --skip-verify"
}

# 日志函数
log() {
    local level=$1
    shift
    local message="$@"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    echo -e "${timestamp} [$level] $message" | tee -a "$LOG_FILE"
}

log_info() {
    log "INFO" "$@"
    echo -e "${BLUE}[INFO]${NC} $@"
}

log_success() {
    log "SUCCESS" "$@"
    echo -e "${GREEN}[SUCCESS]${NC} $@"
}

log_warning() {
    log "WARNING" "$@"
    echo -e "${YELLOW}[WARNING]${NC} $@"
}

log_error() {
    log "ERROR" "$@"
    echo -e "${RED}[ERROR]${NC} $@"
}

log_debug() {
    if [ "$VERBOSE" = true ]; then
        log "DEBUG" "$@"
        echo -e "${PURPLE}[DEBUG]${NC} $@"
    fi
}

# 检查依赖
check_dependencies() {
    log_info "检查依赖..."
    
    local deps=("node" "npm" "php" "composer" "git")
    local missing_deps=()
    
    for dep in "${deps[@]}"; do
        if ! command -v "$dep" &> /dev/null; then
            missing_deps+=("$dep")
        fi
    done
    
    if [ ${#missing_deps[@]} -gt 0 ]; then
        log_error "缺少依赖: ${missing_deps[*]}"
        exit 1
    fi
    
    log_success "依赖检查通过"
}

# 创建备份
create_backup() {
    if [ "$CREATE_BACKUP" != true ]; then
        log_info "跳过备份"
        return 0
    fi
    
    log_info "创建备份..."
    
    local backup_dir="$BACKUP_ROOT/$(date +%Y%m%d-%H%M%S)"
    mkdir -p "$backup_dir"
    
    # 备份当前部署
    if [ -d "$DEPLOY_ROOT" ]; then
        cp -r "$DEPLOY_ROOT"/* "$backup_dir/" 2>/dev/null || true
        log_success "备份创建完成: $backup_dir"
    else
        log_warning "部署目录不存在，跳过备份"
    fi
    
    # 清理旧备份（保留最近10个）
    find "$BACKUP_ROOT" -maxdepth 1 -type d -name "20*" | sort -r | tail -n +11 | xargs rm -rf
}

# 构建项目
build_project() {
    log_info "开始构建项目..."
    
    # 设置环境变量
    export NODE_ENV="$ENVIRONMENT"
    export DEPLOY_TYPE="$DEPLOY_TYPE"
    
    # 配置环境
    log_info "配置环境: $ENVIRONMENT"
    ./deploy-config.sh "$ENVIRONMENT"
    
    if [ $? -ne 0 ]; then
        log_error "环境配置失败"
        exit 1
    fi
    
    # 构建和混淆
    local build_args="-e $ENVIRONMENT -o $OBFUSCATION_LEVEL"
    if [ "$DEPLOY_TYPE" = "saas" ]; then
        build_args="$build_args -z"  # SaaS模式创建压缩包
    fi
    
    log_info "执行构建和混淆..."
    ./build-and-obfuscate.sh $build_args
    
    if [ $? -ne 0 ]; then
        log_error "构建失败"
        exit 1
    fi
    
    log_success "项目构建完成"
}

# 部署前端
deploy_frontend() {
    log_info "部署前端..."
    
    local frontend_source
    if [ "$DEPLOY_TYPE" = "saas" ]; then
        # SaaS模式使用混淆后的代码
        frontend_source="obfuscation/merchant-obfuscated"
    else
        # 私有化部署使用原始代码
        frontend_source="merchant/dist"
    fi
    
    if [ ! -d "$frontend_source" ]; then
        log_error "前端构建产物不存在: $frontend_source"
        exit 1
    fi
    
    # 创建部署目录
    local frontend_deploy_dir="$DEPLOY_ROOT/frontend"
    mkdir -p "$frontend_deploy_dir"
    
    # 复制文件
    cp -r "$frontend_source"/* "$frontend_deploy_dir/"
    
    # 设置权限
    find "$frontend_deploy_dir" -type f -exec chmod 644 {} \;
    find "$frontend_deploy_dir" -type d -exec chmod 755 {} \;
    
    log_success "前端部署完成: $frontend_deploy_dir"
}

# 部署SDK
deploy_sdk() {
    log_info "部署SDK..."
    
    local sdk_source="obfuscation/sdk-obfuscated"
    
    if [ ! -d "$sdk_source" ]; then
        log_error "SDK构建产物不存在: $sdk_source"
        exit 1
    fi
    
    # 创建部署目录
    local sdk_deploy_dir="$DEPLOY_ROOT/sdk"
    mkdir -p "$sdk_deploy_dir"
    
    # 复制文件
    cp -r "$sdk_source"/* "$sdk_deploy_dir/"
    
    # 设置权限
    find "$sdk_deploy_dir" -type f -exec chmod 644 {} \;
    find "$sdk_deploy_dir" -type d -exec chmod 755 {} \;
    
    log_success "SDK部署完成: $sdk_deploy_dir"
}

# 部署后端
deploy_backend() {
    log_info "部署后端..."
    
    local backend_source="webman"
    
    if [ ! -d "$backend_source" ]; then
        log_error "后端源码不存在: $backend_source"
        exit 1
    fi
    
    # 创建部署目录
    local backend_deploy_dir="$DEPLOY_ROOT/backend"
    mkdir -p "$backend_deploy_dir"
    
    # 复制后端文件
    cp -r "$backend_source"/* "$backend_deploy_dir/"
    
    # 安装依赖
    cd "$backend_deploy_dir"
    composer install --no-dev --optimize-autoloader
    
    # 设置权限
    find "$backend_deploy_dir" -type f -name "*.php" -exec chmod 644 {} \;
    find "$backend_deploy_dir" -type d -exec chmod 755 {} \;
    chmod -R 777 "$backend_deploy_dir/runtime"
    
    # 重启服务
    if [ "$ENVIRONMENT" = "production" ]; then
        php start.php restart -d
    else
        php start.php restart
    fi
    
    log_success "后端部署完成: $backend_deploy_dir"
}

# 验证部署
verify_deployment() {
    if [ "$VERIFY_DEPLOYMENT" != true ]; then
        log_info "跳过部署验证"
        return 0
    fi
    
    log_info "验证部署..."
    
    # 检查前端
    local frontend_url="https://merchant.xapptool.cn"  # 需要根据实际配置修改
    if command -v curl &> /dev/null; then
        if curl -f -s "$frontend_url" > /dev/null; then
            log_success "前端验证通过: $frontend_url"
        else
            log_error "前端验证失败: $frontend_url"
            return 1
        fi
    fi
    
    # 检查API
    local api_url="https://api.xapptool.cn/api/health"  # 需要根据实际配置修改
    if curl -f -s "$api_url" > /dev/null; then
        log_success "API验证通过: $api_url"
    else
        log_warning "API验证失败: $api_url"
    fi
    
    # 检查SDK
    local sdk_url="https://sdk.xapptool.cn/web/xapptool.js"  # 需要根据实际配置修改
    if curl -f -s "$sdk_url" > /dev/null; then
        log_success "SDK验证通过: $sdk_url"
    else
        log_warning "SDK验证失败: $sdk_url"
    fi
}

# 运行测试
run_tests() {
    if [ "$SKIP_TESTS" = true ]; then
        log_info "跳过测试"
        return 0
    fi
    
    log_info "运行测试..."
    
    # 前端测试
    if [ -d "merchant" ]; then
        cd merchant
        if [ -f "package.json" ] && grep -q '"test"' package.json; then
            npm test || log_warning "前端测试失败"
        fi
        cd ..
    fi
    
    # 后端测试
    if [ -d "webman" ]; then
        cd webman
        # 这里可以添加后端测试命令
        log_info "后端测试..."
        cd ..
    fi
    
    log_success "测试完成"
}

# 清理旧文件
cleanup_old_files() {
    log_info "清理旧文件..."
    
    # 清理构建产物
    find . -name "dist" -type d -exec rm -rf {} + 2>/dev/null || true
    find . -name "*.log" -type f -mtime +7 -delete 2>/dev/null || true
    find . -name "*.tmp" -type f -delete 2>/dev/null || true
    
    log_success "清理完成"
}

# 主部署流程
main() {
    log_info "开始部署流程..."
    log_info "环境: $ENVIRONMENT, 类型: $DEPLOY_TYPE, 混淆级别: $OBFUSCATION_LEVEL"
    
    # 检查依赖
    check_dependencies
    
    # 创建备份
    create_backup
    
    # 清理旧文件
    cleanup_old_files
    
    # 运行测试
    run_tests
    
    # 构建项目
    build_project
    
    # 部署各个组件
    deploy_frontend
    deploy_sdk
    deploy_backend
    
    # 验证部署
    verify_deployment
    
    log_success "部署完成！"
    
    # 输出部署信息
    echo
    echo -e "${CYAN}=== 部署信息 ===${NC}"
    echo -e "环境: ${GREEN}$ENVIRONMENT${NC}"
    echo -e "类型: ${GREEN}$DEPLOY_TYPE${NC}"
    echo -e "混淆级别: ${GREEN}$OBFUSCATION_LEVEL${NC}"
    echo -e "部署目录: ${GREEN}$DEPLOY_ROOT${NC}"
    echo -e "备份目录: ${GREEN}$BACKUP_ROOT${NC}"
    echo
    
    if [ "$DEPLOY_TYPE" = "saas" ]; then
        echo -e "${YELLOW}注意: 这是SaaS模式部署，代码已混淆${NC}"
    else
        echo -e "${YELLOW}注意: 这是私有化部署，包含完整源代码${NC}"
    fi
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -e|--environment)
            ENVIRONMENT="$2"
            shift 2
            ;;
        -t|--type)
            DEPLOY_TYPE="$2"
            shift 2
            ;;
        -o|--obfuscation)
            OBFUSCATION_LEVEL="$2"
            shift 2
            ;;
        --deploy-root)
            DEPLOY_ROOT="$2"
            shift 2
            ;;
        --backup-root)
            BACKUP_ROOT="$2"
            shift 2
            ;;
        --skip-backup)
            CREATE_BACKUP=false
            shift
            ;;
        --skip-verify)
            VERIFY_DEPLOYMENT=false
            shift
            ;;
        --skip-tests)
            SKIP_TESTS=true
            shift
            ;;
        -v|--verbose)
            VERBOSE=true
            shift
            ;;
        -h|--help)
            show_help
            exit 0
            ;;
        *)
            echo -e "${RED}错误: 未知参数 $1${NC}"
            show_help
            exit 1
            ;;
    esac
done

# 创建必要的目录
mkdir -p "$BACKUP_ROOT"
mkdir -p "$(dirname "$LOG_FILE")"

# 运行主函数
main